// SuppoertHangerIterator.cpp: implementation of the SuppoertHangerIterator class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "phsshare.h"
#include "SupportHangerIterator.h"
#include "Part.h"
#include "JointFunction.h"
#include "Joint.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SupportHangerIterator::SupportHangerIterator(SupportHanger* pSH)
{
	ASSERT(pSH);
	m_pSH = pSH;
}

SupportHangerIterator::~SupportHangerIterator()
{

}

void SupportHangerIterator::Begin()
{
	Part* pPart = NULL;
	if(m_pSH == NULL)
		SetData(NULL);

	ClearOver();
	pPart = m_pSH->SupportHangerEntry();
	if(pPart == NULL)
	{
		FindNoOverNote();
		return;
	}
	m_theHaveOvers.SetAt(pPart, pPart);
	m_OverStack.push(pPart);
	SetData(pPart);
}

void SupportHangerIterator::Next()
{
	Part* pCurPart = NULL;
	Part* pPart = NULL;

	while(!m_OverStack.empty())
	{
		pCurPart = m_OverStack.top();
		ASSERT(pCurPart);
		JointInfo info(pCurPart);
		JointFunction* pJoint = info.GetFirst();
		while(pJoint != NULL)
		{
			if(pJoint->GetJoint() == NULL)
			{
				pJoint = info.GetNext();
				continue;
			}
			else
			{
				JointFunction* pTempJoint = pJoint->GetJoint()->GetPrev();
				if(pTempJoint != pJoint)
				{
					ASSERT(pTempJoint);
					ASSERT(pTempJoint->GetOwner()->IsKindOf(UE_RUNTIME_CLASS(Part)));
					pPart = static_cast<Part*>(pTempJoint->GetOwner());
				}
				else
				{
					ASSERT(pJoint->GetJoint()->GetNext()->GetOwner()->IsKindOf(UE_RUNTIME_CLASS(Part)));

					pPart = static_cast<Part*>(pJoint->GetJoint()->GetNext()->GetOwner());
					ASSERT(pJoint == pJoint->GetJoint()->GetPrev());
				}
				if(!IsOver(pPart))
				{
					m_theHaveOvers.SetAt(pPart, pPart);
					m_OverStack.push(pPart);
					SetData(pPart);
					return;
				}
			}
			pJoint = info.GetNext();
		}
		m_OverStack.pop();
	}
	FindNoOverNote();
}

BOOL SupportHangerIterator::IsOver(Part* pPart)
{
	Part* pTemp = NULL;
	
	return m_theHaveOvers.Lookup(pPart, pTemp);
}

void SupportHangerIterator::ClearOver()
{
	while(!m_OverStack.empty())
	{
		m_OverStack.pop();
	}
	m_theHaveOvers.RemoveAll();
}

void SupportHangerIterator::FindNoOverNote()
{
	Part* pPart = NULL;

	ASSERT(m_pSH);

	PartManager::Iterator* pIt = m_pSH->GetPartManager().NewIterator();
	ASSERT_MEMORY_VALID(pIt, NORETURN);
	
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		pPart = pIt->Get();
		ASSERT(pPart);
		if(!pPart->IsAttach() && !pPart->IsDeleteState() && !IsOver(pPart))
		{
			ASSERT(m_OverStack.size() == 0);
			m_theHaveOvers.SetAt(pPart, pPart);
			m_OverStack.push(pPart);
			SetData(pPart);
			delete pIt;
			return ;
		}
	}
	delete pIt;
	SetData(NULL);
}